﻿using UnityEngine;
using System.Collections;

public class EnemyAI : MonoBehaviour 
{	
	public Player myPlayer,enemy;
	private Vector3[] spawns = {new Vector3(-80f, .5f, 80f), new Vector3(-80f, .5f, -80f), new Vector3(80f, .5f, -80f), new Vector3(80f, .5f, 80f)};
	public int it1Loc=-1,it2Loc=-1,myLoc,enemyLoc=-1;
	private Group it1Scout,it2Scout,enemyScout;
	private ArrayList scoutGroups = new ArrayList();
	private ArrayList igotchugroups= new ArrayList();
	private ArrayList interceptedGroups = new ArrayList();
	private ArrayList usedUnits = new ArrayList();
	private int randomCounter=0;
	public int aispeed=200;
	public int dirty =0;
	class Pair{
		public Group my, theirs;
	}
	// Update is called once per frame
	void Update () 
	{
		cleanStructures();
		getUpgrades();
		checkScouts();
		checkEnemyUnits();
		doRandomThings();
		if(dirty++>10000)
		{
			//myPlayer.gold+=20;
			usedUnits.Clear();
			dirty=0;
		}
		//attack (spawns[enemyLoc].x,spawns[enemyLoc].z,10);
	}
	void checkEnemyUnits(){
		GroupManager man = (GroupManager)GameObject.Find("Managers").GetComponent("GroupManager");
		for(int i=0;i<man.groups.Count;i++){
			Group g = (Group)man.groups[i];
			if(g.myUnits.Count!=0 && ((Unit)g.myUnits[0]).owner!=myPlayer && !igotchugroups.Contains(g)){
				Vector3 dist = g.target-myPlayer.commandCenter.obj.transform.position;
				dist.y=0;
				if(dist.magnitude<40){
					intercept (g);
					igotchugroups.Add(g);
				}
			}
		}
	}
	void intercept(Group g){
		int num =g.myUnits.Count;
		Pair p = new Pair();
		Group my;
		if(myPlayer.getUnits().Count-usedUnits.Count<num){
			int need = num-(myPlayer.getUnits().Count-usedUnits.Count);
			for(int i=0;i<need;i++)if(usedUnits.Count>0)
				usedUnits.RemoveAt(0);
			else break;
			if(usedUnits.Count==0)
				my=intercept(g.target.x,g.target.z,myPlayer.getUnits().Count);
			else
				my=intercept(g.target.x,g.target.z,num-1);
		}else{
			my=intercept(g.target.x,g.target.z,num);
		}
		if(my==null)
			return;
		p.my=my;
		p.theirs=g;
		interceptedGroups.Add(p);
	}

	void checkScouts(){
		for(int i=0;i<scoutGroups.Count;){
			Group g = (Group)scoutGroups[i];
			if(g.myUnits.Count==0){
 				scoutGroups.RemoveAt(i);
				continue;
			}
			bool done = true;
			foreach(Unit u in g.myUnits)if(!u.isDead()){
				Vector3 dist=(u.obj.transform.position-g.target);
				dist.y=0;
				if(dist.magnitude<10){
					usedUnits.Remove(u);
				}
				else done=false;
			}
			if(done){
				scoutGroups.RemoveAt(i);
			}
			else
				i++;
		}
	}
	void doRandomThings(){
		if(randomCounter++>aispeed){
			double randomAct=Random.value;
			int randomNumUnits= (int)(Mathf.Min(Random.value+.5f,1f)*(myPlayer.getUnits().Count-usedUnits.Count));
			if(randomAct<.1){
				sendScout(spawns[it1Loc].x,spawns[it1Loc].z,randomNumUnits);
			}
			else if(randomAct<.2){
				sendScout(spawns[it2Loc].x,spawns[it2Loc].z,randomNumUnits);
			}
			else if(randomAct<.7){
				Rect bounds = NeutralSpawner.singleton.spawnBounds;
				float rX = bounds.xMin+Random.value*bounds.width,
					rY = bounds.yMin+Random.value*bounds.height;
				sendScout(rX,rY,randomNumUnits);
			}
			else if(randomNumUnits>enemy.spawnGroup.myUnits.Count){
				sendScout(spawns[enemyLoc].x,spawns[enemyLoc].z,randomNumUnits);
			}
			randomCounter=0;
		}
	}
	void getUpgrades(){
		if((enemy.atkSpeedUpgrade>myPlayer.atkSpeedUpgrade ||
		    myPlayer.gold-UpgradeSystem.getCost(myPlayer.atkSpeedUpgrade)>enemy.gold)&& 
		   	myPlayer.gold>UpgradeSystem.getCost(myPlayer.atkSpeedUpgrade))
		{
			myPlayer.gold-=UpgradeSystem.getCost(myPlayer.atkSpeedUpgrade);
			myPlayer.atkSpeedUpgrade++;
		}
		if((enemy.attackUpgrade>myPlayer.attackUpgrade ||
		   myPlayer.gold-UpgradeSystem.getCost(myPlayer.attackUpgrade)>enemy.gold)&&  
		   myPlayer.gold>UpgradeSystem.getCost(myPlayer.attackUpgrade))
		{
			myPlayer.gold-=UpgradeSystem.getCost(myPlayer.attackUpgrade);
			myPlayer.attackUpgrade++;
		}
		if((enemy.speedUpgrade>myPlayer.speedUpgrade ||
		   myPlayer.gold-UpgradeSystem.getCost(myPlayer.speedUpgrade)>enemy.gold)&&
		   myPlayer.gold>UpgradeSystem.getCost(myPlayer.speedUpgrade))
		{
			myPlayer.gold-=UpgradeSystem.getCost(myPlayer.speedUpgrade);
			myPlayer.speedUpgrade++;
		}
		if((enemy.lifeUpgrade>myPlayer.lifeUpgrade ||
		   myPlayer.gold-UpgradeSystem.getCost(myPlayer.lifeUpgrade)>enemy.gold)&& 
		   myPlayer.gold>UpgradeSystem.getCost(myPlayer.lifeUpgrade))
		{
			myPlayer.gold-=UpgradeSystem.getCost(myPlayer.lifeUpgrade);
			myPlayer.lifeUpgrade++;
		}
	}
	void cleanStructures(){
		for(int i=0;i<usedUnits.Count;){
			Unit u = (Unit)usedUnits[i];
			if(u.isDead())
				usedUnits.RemoveAt(i);
			else 
				i++;
		}
		for(int i=0;i<igotchugroups.Count;){
			Group g = (Group) igotchugroups[i];
			if(g.myUnits.Count==0){
				igotchugroups.RemoveAt(i);
			}
			else 
				i++;
		}
		for(int i=0;i<interceptedGroups.Count;){
			Pair p = (Pair) interceptedGroups[i];
			if(p.theirs.myUnits.Count==0){
				if(p.my.myUnits.Count>0)
					foreach(Unit u in p.my.myUnits){
						usedUnits.Remove(u);
						myPlayer.spawnGroup.myUnits.Add (u);
						u.myGroup=myPlayer.spawnGroup;
					}
				interceptedGroups.RemoveAt(i);
			}
			else 
				i++;
		}
	}
	Group intercept(float dstx,float dsty, int num){
		if(usedUnits.Count+num<=myPlayer.getUnits().Count){
			Group g = new Group();
			g.target=new Vector3(dstx,0,dsty);
			int x=0;
			foreach(Unit u in myPlayer.getUnits()){
				if(!usedUnits.Contains(u)){
					g.myUnits.Add(u);
					u.myGroup=g;
					usedUnits.Add(u);
					x++;
				}
				if(x>=num)
					break;
			}
			GroupManager man = (GroupManager)GameObject.Find("Managers").GetComponent("GroupManager");
			man.groups.Add(g);
			return g;
		}
		return null;
	}
	Group sendScout(float dstx,float dsty, int num){
		if(usedUnits.Count+num<myPlayer.getUnits().Count){
			Group g = new Group();
			g.target=new Vector3(dstx,0,dsty);
			int x=0;
			foreach(Unit u in myPlayer.getUnits()){
				if(!usedUnits.Contains(u)){
					g.myUnits.Add(u);
					u.myGroup=g;
					usedUnits.Add(u);
					x++;
				}
				if(x>=num)
					break;
			}
			GroupManager man = (GroupManager)GameObject.Find("Managers").GetComponent("GroupManager");
			man.groups.Add(g);
			scoutGroups.Add(g);
			return g;
		}
		return null;
	}
}
